function App() {

}

App.prototype.init = function() {
   var current = this;

   var title = _helper.document.documentElement.firstChild;
   while (title && (title.nodeType!=Node.ELEMENT_NODE || title.localName!="title")) {
      title = title.nextSibling;
   }
   if (title) {
      document.title = title.textContent;
   }

   this.controls = document.createElement("div");
   this.controls.setAttribute("id","-app-controls");
   document.body.appendChild(this.controls);

   this.prevButton = document.createElement("button");
   this.prevButton.onclick = function() {
      current.onPrevious();
   }
   this.prevButton.appendChild(document.createTextNode("Previous"));
   this.controls.appendChild(this.prevButton);

   this.toc = document.createElement("select");
   this.toc.setAttribute("id","-app-toc");
   this.controls.appendChild(this.toc);

   this.nextButton = document.createElement("button");
   this.nextButton.onclick = function() {
      current.onNext();
   }
   this.nextButton.appendChild(document.createTextNode("Next"));
   this.controls.appendChild(this.nextButton);

   this.content = document.createElement("div");
   this.content.setAttribute("id","-app-content");
   document.body.appendChild(this.content);

   window.addEventListener('resize',function() {
      current.onResize();
   },false);
   this.onResize();

   this.loadTOC();
   this.changeSection();

   this.toc.onchange = function() {
      try {
      if (current.tocChangeTimer) {
         clearTimeout(current.tocChangeTimer);
      }
      current.tocChangeTimer = setTimeout(function() {
         current.tocChangeTimer = null;
         current.changeSection();
      },250);
      } catch (ex) {
         alert(ex);
      }
   };

   window.addEventListener('keypress',function(event) {
      if (event.altKey) {
         switch (event.keyCode) {
            case 37:
               current.onPrevious();
               break;
            case 38:
               current.onParent();
               break;
            case 39:
               current.onNext();
         }
      }
      switch (event.charCode) {
         case 32:
            current.onNext();
            break;
         case 115:
            current.toc.selectedIndex = 0;
            current.changeSlide();
      }
      //alert(event.keyCode+" "+event.charCode);
   },false)
}

App.prototype.onPrevious = function() {
   if (this.toc.selectedIndex>0) {
      this.toc.selectedIndex--;
      this.changeSection();
   }
}

App.prototype.onNext = function() {
   if (this.toc.selectedIndex<(this.sections.length-1)) {
      this.toc.selectedIndex++;
      this.changeSection();
   }
}

App.prototype.onParent = function() {
   var section = this.sections[this.toc.selectedIndex];
   if (section.parent) {
      this.toc.selectedIndex = section.parent.index;
      this.changeSection();
   }
}

App.prototype.makeSectionLink = function(parent,atStart,title) {
   var sectionRef = document.createElement("p");
   if (atStart && this.content.firstChild) {
      parent.insertBefore(sectionRef,parent.firstChild);
   } else {
      parent.appendChild(sectionRef);
   }
   sectionRef.className = "section-ref";
   var icon = document.createElement("span");
   sectionRef.appendChild(icon);
   icon.className = "icon";
   icon.appendChild(document.createTextNode("\u2191"));
   icon = document.createElement("span");
   sectionRef.appendChild(icon);
   icon.className = "icon";
   icon.appendChild(document.createTextNode("\xa7"));
   sectionRef.appendChild(document.createTextNode(" "+title));
   return sectionRef;
}

App.prototype.changeSection = function() {
   if (this.toc.selectedIndex==0) {
      this.nextButton.disabled = false;
      this.prevButton.disabled = true;
   } else if (this.toc.selectedIndex==(this.sections.length-1)) {
      this.nextButton.disabled = true;
      this.prevButton.disabled = false;
   } else {
      this.nextButton.disabled = false;
      this.prevButton.disabled = false;
   }
   var current = this;
   var section = this.sections[this.toc.selectedIndex];
   if (section.element.nodeType==Node.ELEMENT_NODE) {
      section.element.setAttribute("top","true");
   }
   var fragment = _helper.applyTransform(section.type,section.element);
   if (section.element.nodeType==Node.ELEMENT_NODE) {
      section.element.removeAttribute("top");
   }
   this.replaceContent(fragment);
   if (section.level>1) {
      var parentRef = this.makeSectionLink(this.content, true, section.parent.title);
      parentRef.onclick = function() {
         current.toc.selectedIndex = section.parent.index;
         current.changeSection();
      }
   }
   var nextLevel = section.level+1;
   var makeAction = function(ref,index) {
      ref.onclick = function() {
         current.toc.selectedIndex = index;
         current.changeSection();
      }
   }
   for (var i=this.toc.selectedIndex+1; i<this.sections.length && this.sections[i].level==nextLevel; i++) {
      var childRef = this.makeSectionLink(this.content, false, this.sections[i].title);
      makeAction(childRef,i);
   }
   window.scroll(0,0);
}

App.prototype.replaceContent = function(fragment) {
   var current = this.content.firstChild;
   while (current) {
      var e = current;
      current = current.nextSibling;
      e.parentNode.removeChild(e);
   }

   current = fragment.firstChild;
   while (current) {
      this.content.appendChild(current);
      current = current.nextSibling;
   }
}

App.prototype.onResize = function() {
   this.controls.style.top = (window.innerHeight-43)+"px";
   this.controls.style.width = (window.innerWidth-10)+"px";
}

App.prototype.loadTOC = function() {
   var parent = _helper.document.documentElement;
   this.sections = [];

   this.sections.push({ type: "info", element: _helper.document, title: "Abstract", level: 1, index: 0});
   var option = document.createElement("option");
   this.toc.appendChild(option);
   option.appendChild(document.createTextNode("Abstract"));
   option.setAttribute("value",""+(this.sections.length-1));

   var level = 1;

   var current = parent.firstChild;
   var parentSection = null;

   while (current) {
      if (current.nodeType==Node.ELEMENT_NODE && (current.localName=="section" || current.localName=="appendix")) {
         // add to TOC

         // find title

         var title = current.firstChild;
         while (title && (title.nodeType!=Node.ELEMENT_NODE || title.localName!="title")) {
            title = title.nextSibling;
         }
         if (title) {
            // move to child section only if we have a title

            this.sections.push({ type: "section", element: current, title: title.textContent, level: level, parent: parentSection});
            this.sections[this.sections.length-1].index = this.sections.length-1;

            var option = document.createElement("option");
            this.toc.appendChild(option);
            var indent = level-1;
            if (indent>5) {
               indent = 5;
            }
            option.className = "-app-indent-"+indent;
            option.appendChild(document.createTextNode(title.textContent));
            option.setAttribute("value",""+(this.sections.length-1));
            parent = current;
            current = parent.firstChild;
            parentSection = this.sections[this.sections.length-1];
            level++;
            continue;
         }


      }
      current = current.nextSibling;
      while (!current && level!=1) {
         current = parent.nextSibling;
         parent = parent.parentNode;
         parentSection = parentSection ? parentSection.parent : null;
         level--;
      }
   }

   this.sections.push({ type: "bibliography", element: _helper.document, title: "Bibliography", level: 1, index: 0});
   option = document.createElement("option");
   this.toc.appendChild(option);
   option.appendChild(document.createTextNode("Bibliography"));
   option.setAttribute("value",""+(this.sections.length-1));
}

var app = new App();
app.init();

